/**
 * Created with CLion.
 * Description: 
 * User: loong
 * Date: 2023/12/19
 * Time: 20:56
 */

#ifndef CES_CONFIG_NODE_H
#define CES_CONFIG_NODE_H

#include <list>
#include <map>
#include <memory>
#include <string>
#include "ConfigGlobal.h"

namespace CES::Config {
    class Node;
    using NodeSPtr  = std::shared_ptr<Node>;
    using NodeWPtr  = std::weak_ptr<Node>;

    using NodeList  = std::list<NodeSPtr>;
    using NodeAttrs = std::map<std::string, std::string>;

    class NodeImpl;
    class CONFIG_MODULE_EXPORT Node
        : public std::enable_shared_from_this<Node>
    {
        // friend class Doc;

    public:
        explicit Node(std::string _key, std::string _value = "");

        Node();

        virtual ~Node() = default;

        static NodeSPtr FromString(const std::string & source);

        std::string ToString(const std::string & _indent = "\t");

        NodeList Children();

        NodeSPtr AddChildren(const NodeList & _children);

        NodeSPtr RemoveChildren(const NodeList & _children);

        NodeList Child(const std::string & _name);

        NodeSPtr RemoveChild(const std::string & _name);
#pragma region XML-USE
        NodeAttrs Attrs();

        std::string Attr(const std::string & _attr_name);

        NodeSPtr AddAttr(const std::string & _attr, const std::string & _value);

        NodeSPtr AddAttr(const NodeAttrs & _attr);

        NodeSPtr RemoveAttr(const std::string & _attr);

        NodeSPtr SetTagName(const std::string & _tag);

        std::string TagName();

        NodeSPtr SetValue(const std::string & _value);

        std::string Value();
#pragma endregion

    protected:
        std::shared_ptr<NodeImpl> node_impl_;
    };

}// namespace CES::Config

#endif//CES_CONFIG_NODE_H
